Lambda(Go)でDynamoDBのデータ取得・登録(GET/POST)をしてみた
こんにちは、ゲームソリューショングループのsoraです。
今回は、Lambda(Go)でDynamoDBのデータ取得・登録(GET/POST)をしてみたことを書いていきます。
データは都道府県名・県庁所在地・地域をカラムとして持つもので、都道府県名を渡すことで県庁所在地と地域を取得でき、全ての値を与えることで登録もできるようにしていきます。
LambdaとDynamoDBの作成
今回はTerraformを使って作成します。
Terraformソースコード
まずは、AWS側で必要なサービスを作成します。
terraform { #AWSプロバイダーのバージョン指定 required_providers { aws = { source = "hashicorp/aws" version = "~> 4.51.0" } } } #AWSプロバイダーの定義 provider aws { region = "ap-northeast-1" } #Lambda用IAMロールの信頼関係の定義 data aws_iam_policy_document assume_role { statement { effect = "Allow" principals { type = "Service" identifiers = ["lambda.amazonaws.com"] } actions = ["sts:AssumeRole"] } } #Lambda用IAMロールの作成 resource aws_iam_role iam_for_lambda { name = "Prefecture_Lambda_Role" assume_role_policy = data.aws_iam_policy_document.assume_role.json managed_policy_arns=["arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"] } #Lambdaへの配置ファイルのzip化 data archive_file lambda { type = "zip" source_file = "dynamodbapi" output_path = "handler.zip" } #Lambdaの作成 resource aws_lambda_function Prefecture_Lambda { filename = "handler.zip" function_name = "DynamoDBAPI_Lambda" role = aws_iam_role.iam_for_lambda.arn handler = "dynamodbapi" source_code_hash = data.archive_file.lambda.output_base64sha256 runtime = "go1.x" } #DynamoDBの作成 resource aws_dynamodb_table prefecture_table { name = "PrefecturesTable" billing_mode = "PAY_PER_REQUEST" hash_key = "PrefectureName" range_key = "Region" attribute { name = "PrefectureName" type = "S" } attribute { name = "Region" type = "S" } } #初期データファイルの取得 locals { csv_data = file("prefectual.csv") dataset = csvdecode(local.csv_data) } #テーブルアイテムの登録 resource aws_dynamodb_table_item table_item { for_each = { for record in local.dataset : record.prefecturename => record } table_name = aws_dynamodb_table.prefecture_table.name hash_key = aws_dynamodb_table.prefecture_table.hash_key range_key = aws_dynamodb_table.prefecture_table.range_key item = <<ITEM { "PrefectureName": {"S": "${each.value.prefecturename}"}, "PrefecturalCapital": {"S": "${each.value.prefecturalcapital}"}, "Region": {"S": "${each.value.region}"} } ITEM }
DynamoDBへ初期値として登録するデータは、CSVファイルに記載してTerraform側でfor_eachを使って登録します。
prefecturename,prefecturalcapital,region Hokkaido,Sapporo,Hokkaido Tokyo,Tokyo,Kanto Aichi,Nagoya,Chubu Osaka,Osaka,Kansai Hukuoka,Hakata,Kyushu
Lambdaで使用するコード(Go)
Goソースコード
GETメソッドで都道府県名を渡すことで県庁所在地と地域を取得でき、POSTメソッドでデータの登録ができる関数です。
aws-sdk-goを直接使う場合は複雑になるため、今回はguregu/dynamoを使用しています。
エラー処理は全然入れていないため、実際に使う場合は入れた方が良いです。
今回はAPI Gatewayまでは作りませんが、後に接続することを意識してAPIGatewayProxyRequestの形で受け取るようにしています。
package main import ( "fmt" // Go用のLambdaプログラミングモデル "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/guregu/dynamo" ) type Event struct { PrefectureName string `json:"PrefectureName"` Region string `json:"Region"` PrefecturalCapital string `json:"PrefecturalCapital"` } // メソッドに応じて処理分岐 func DBOperateAPI(req events.APIGatewayProxyRequest) () { db := dynamo.New(session.New(), &aws.Config{Region: aws.String("ap-northeast-1")}) table := db.Table("PrefecturesTable") switch req.HTTPMethod { case "GET": prefecture_name := req.QueryStringParameters["PrefectureName"] var results []Event // ソートキーまで指定する場合は // table.Get("PrefectureName", prefecture_name).Range("Region", dynamo.Equal, prefecture_region).One(&result) // PrefectureNameが一致するものを全て取得 table.Get("PrefectureName", prefecture_name).All(&results) fmt.Printf("%v\n", results) case "POST": prefecture_name := req.QueryStringParameters["PrefectureName"] prefecture_region := req.QueryStringParameters["Region"] prefecture_capital := req.QueryStringParameters["PrefecturalCapital"] evt := Event{PrefectureName: prefecture_name, Region: prefecture_region, PrefecturalCapital: prefecture_capital} table.Put(evt).Run() } } func main() { lambda.Start(DBOperateAPI) }
デプロイ
コードの準備ができたため、実行していきます。
作成したGoファイルのビルド
GoファイルをLambdaに持っていく前に、ビルドをする必要があります。
$ go mod tidy $ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o dynamodbapi
ビルドが終わったら、dynamodbapiという名前のファイルができています。
Terraform実行
作成したTerraformのコードを実行して構築します。
$ terraform init $ terraform apply
正常に構築できていることが確認できます。
DynamoDBに初期値として登録したデータも登録されています。
Lambdaでのテスト
構築できたのでLambdaでテストしていきます。
テストイベントのJSONは、APIGatewayProxyRequestの形式に合わせて設定します。
まず検索から実行します。
{ "HTTPMethod": "GET", "QueryStringParameters": { "PrefectureName": "Hokkaido" } }
printfで表示させているため、ログ出力に取得した結果が表示されています。
次に登録を実行します。
{ "HTTPMethod": "POST", "QueryStringParameters": { "PrefectureName": "Gifu", "Region": "Chubu", "PrefecturalCapital": "Gifu" } }
DynamoDBを見ると、POSTで渡したデータが登録されています。
参考記事
気楽にDynamoDBを使おう
API Gateway から Lambda にパラメータを渡す
最後に
今回は、Lambda(Go)でDynamoDBへのデータ取得・登録(GET/POST)してみたことを記事にしました。
どなたかの参考になると幸いです。